import allure
import pytest
import requests
from help_api.api_keyword.api_key import ApiKey
from help_api.params.allParams import URL
import logging
# 逻辑层

# 发单员正常发起帮助
class ApiCase03:

    token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcGVuaWQiOiJvNkttbTVGeTlPd1l5dDRFMEV1RnIwcVFRX1lnIiwidHlwZSI6Ind4bSIsImlkIjoxMzQ5LCJyb2xlX2lkIjozLCJpYXQiOjE3NDQ2OTI1MjMsImV4cCI6MTc0NDczNTcyM30.JrPa5LVhq7tGuk1ldsMoU9rtkFWB0ZVLJXyOs7U5b4M'

    # 初始化工具类
    apiKey = ApiKey()

    """获取服务列表  /api/server/get/uid"""
    def test_serverList(self):
        apiKey = ApiKey()
        allure.dynamic.title('获取服务列表')  # 动态获取参数生成标题
        with allure.step(f"发送获取服务列表请求"):
            # 准备请求数据
            json = {"uid": "14176"}
            url = f"{URL}/api/server/get/uid"  # 构建完整的 URL
            headers = {'token': self.token}
            response = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'接口请求响应信息:{response.text}')
            logging.info(f'响应状态码:{response.status_code}')
            logging.info(f'响应头:{response.headers}')
            result = response.json()  # 获取响应结果
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")

            assert result.get('code') == 1, '响应状态码与预期不符'
            assert apiKey.get_text(response.text, 'data[0].server_name') != '', '未找到对应服务'
            # 数据库断言是一种在数据库中用于确保数据完整性和一致性的机制
            # 断言是一个数据库对象，它包含一个布尔表达式，用于指定数据库中的数据必须满足的条件。可以将断言看作是一种更高级、更灵活的约束，它可以基于多个表或复杂的业务规则来定义数据的合法性。
            # 其主要作用是在数据库操作（如插入、更新或删除数据）时，自动检查数据是否满足特定的条件。如果数据不满足断言定义的条件，数据库系统将拒绝执行相应的操作，从而保证数据库中数据的准确性和一致性。
            # 优势方面，断言可以表达非常复杂的约束条件，能够涵盖多个表之间的关系以及基于业务规则的复杂验证。
            # 局限性在于，断言的定义和维护可能相对复杂，特别是对于复杂的业务规则，编写和理解断言的条件表达式可能会有一定难度。
            assert apiKey.db_mysql_select(table='dl_server', field='dl_id', value=apiKey.get_4text(response.text, 'data[0].dl_id')) != '', '未找到对应服务'
        return response

    """发起服务  /api/help/add"""
    def test_addhelp(self):
        allure.dynamic.title('发起服务')  # 动态获取参数生成标题
        apiKey=ApiKey()
        with allure.step('获取服务列表'):
            res1 = self.test_serverList()
        with allure.step('发送发起服务请求'):
            url = f"{URL}/api/help/add"  # 构建完整的 URL
            json = {
                    "openid": "o6Kmm5Fy9OwYyt4E0EuFr0qQQ_Yg",
                    "mu": "z1号楼107",
                    "wx_id": "1369",
                    "form_id": "the formId is no longer available in develop or trial version of this mini program",
                    "title": f"{apiKey.get_text(res1.text, 'data[0].server_name')}",
                    "des": "day4.14",
                    "total_fee": "2"
            }
            headers = {'token': self.token}
            response = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"发不服务接口返回信息校验接打印"):
            logging.info(f'发起服务接口请求响应信息:{response.text}')
            logging.info(f'响应状态码:{response.status_code}')
            logging.info(f'响应头:{response.headers}')
            result = response.json()  # 获取响应结果（只调用一次 json()）
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")
            # 断言响应消息
            assert result.get('msg') == '操作成功', (
                f"响应消息与预期不符\n"
                f"预期消息：{'操作成功'}\n"
                f"实际消息：{result.get('msg')}"
            )
            assert result.get('code') == 1, '响应状态码与预期不符'
            assert apiKey.get_text(response.text, 'oid') != '', '未找到对应服务'
            # 数据库断言
            assert apiKey.db_mysql_select(table='helplist', field='id', value=apiKey.get_text(response.text, 'oid')) != '', '未找到对应服务'
        return response

    """查看发出的服务"""
    def test_helpList(self):
        apiKey = ApiKey()
        allure.dynamic.title('查看发出的服务')  # 动态获取参数生成标题
        with allure.step('调用新发布服务的接口'):
            res1 = self.test_addhelp()
        with allure.step(f"查看发出的服务"):
            # 准备请求数据
            json = {
                "fields": "helplist.*,wxuser.phone,wxuser.dphone,wxuser.avatar_url,wxuser.nick_name",
                "wheres": f"helplist.id={apiKey.get_text(res1.text, 'oid')}",
                "sorts": "helplist.create_time asc"
            }
            url = f"{URL}/api/help/get2"  # 构建完整的 URL
            headers = {'token': self.token}
            res2 = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'查看发出的服务接口请求响应信息:{res2.text}')
            logging.info(f'响应状态码:{res2.status_code}')
            logging.info(f'响应头:{res2.headers}')
            result = res2.json()  # 获取响应结果（只调用一次 json()）
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")

            assert result.get('code') == 1, '响应状态码与预期不符'  # 断言响应状态码
            assert apiKey.get_text(res1.text, 'oid') == apiKey.get_text(res2.text, 'data.list[0].id'), '未找到对应服务'   # 断言响应消息
            assert apiKey.db_mysql_select(table='helplist', field='id', value=apiKey.get_text(res2.text, 'data.list[0].id')) != '', '未找到对应服务'  # 数据库断言
            logging.info('查看发出的服务测试通过')
        return res2

    """支付  /api/help/update/state"""
    def test_payhelp(self):
        apiKey = ApiKey()
        allure.dynamic.title('支付')  # 动态获取参数生成标题
        with allure.step('查看服务列表'):
            res1 = self.test_helpList()
        with allure.step(f"支付"):
            # 准备请求数据
            json = {
                'title': apiKey.get_text(res1.text, 'data.list[0].title'),
                'openid': apiKey.get_text(res1.text, 'data.list[0].openid'),
                "oid": apiKey.get_text(res1.text, 'data.list[0].id'),
                "total_fee": apiKey.get_text(res1.text, 'data.list[0].total_fee')
            }
            url = f"{URL}/api/help/pay"  # 构建完整的 URL
            headers = {'token': self.token}
            res2 = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'支付接口请求响应信息:{res2.text}')
            logging.info(f'响应状态码:{res2.status_code}')
            logging.info(f'响应头:{res2.headers}')
            result = res2.json()  # 获取响应结果（只调用一次 json()）
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")
            # 断言响应消息
            assert result.get('msg') == '操作成功', (
                f"响应消息与预期不符\n"
                f"预期消息：{'操作成功'}\n"
                f"实际消息：{result.get('msg')}"
            )
            db=apiKey.db_mysql_select2()
            assert result.get('code') == 1, '响应状态码与预期不符'  # 断言响应状态码
            assert db.execute(f"select * from helplist where id={apiKey.get_text(res1.text, 'data.list[0].id')} and state = '1' ") != '', '未找到对应订单'
            logging.info('支付成功')
        return res2

    def test_payhelp2(self):
        apiKey = ApiKey()
        allure.dynamic.title('支付')  # 动态获取参数生成标题
        with allure.step('查看服务列表'):
            res1 = self.test_helpList()
        with allure.step(f"支付"):
            # 准备请求数据
            json = {
                'state': '1',
                "id": apiKey.get_text(res1.text, 'data.list[0].id')
            }
            url = f"{URL}/api/help/update/state"  # 构建完整的 URL
            headers = {'token': self.token}
            res2 = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'支付接口请求响应信息:{res2.text}')
            logging.info(f'响应状态码:{res2.status_code}')
            logging.info(f'响应头:{res2.headers}')
            result = res2.json()  # 获取响应结果
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")
            # 断言响应消息
            assert result.get('msg') == '修改成功', (
                f"响应消息与预期不符\n"
                f"预期消息：{'修改成功'}\n"
                f"实际消息：{result.get('msg')}"
            )
            db = apiKey.db_mysql_select2()
            assert result.get('code') == 1, '响应状态码与预期不符'  # 断言响应状态码
            assert db.execute(
                f"select * from helplist where id={apiKey.get_text(res1.text, 'data.list[0].id')} and state = '1' ") != '', '未找到对应订单'
            logging.info('支付成功')
        return res2

    """接单 /api/help/jd"""
    def test_jd(self, token_fix):
        apiKey, token, res, token_random, uid = token_fix
        allure.dynamic.title('接单')  # 动态获取参数生成标题
        with allure.step('调用支付的接口'):
            res1 = self.test_helpList()
        with allure.step(f"接单员接单"):
            # 准备请求数据
            json = {
                "jd_id": 1349,
                "id": apiKey.get_text(res1.text, 'data.list[0].id'),
                "openid": apiKey.get_text(res1.text, 'data.list[0].openid'),
                "form_id": "the formId is no longer available in develop or trial version of this mini program",
                "title": apiKey.get_text(res1.text, 'data.list[0].title'),
                "order_num": apiKey.get_text(res1.text, 'order_num')
            }
            url = f"{URL}/api/help/jd"  # 构建完整的 URL
            headers = {'token': token, 'uid': uid}
            res2 = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'接单接口请求响应信息:{res2.text}')
            logging.info(f'响应状态码:{res2.status_code}')
            logging.info(f'响应头:{res2.headers}')
            result = res2.json()  # 获取响应结果（只调用一次 json()）
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")
            # 断言响应消息
            assert result.get('msg') == '修改成功', (
                f"响应消息与预期不符\n"
                f"预期消息：{'修改成功'}\n"
                f"实际消息：{result.get('msg')}"
            )
            db = apiKey.db_mysql_select2()
            assert result.get('code') == 1, '响应状态码与预期不符'  # 断言响应状态码
            assert db.execute(f"select * from helplist where id={apiKey.get_text(res1.text, 'data.list[0].id')} and state = '2' ") != '', '取消失败'
            logging.info('取消已发出的服务测试通过')
        return res2

    """完成订单  /api/help/confirm"""
    def test_finish(self):
        apiKey = ApiKey()
        allure.dynamic.title('完成订单')  # 动态获取参数生成标题
        with allure.step('调用服务列表的接口'):
            res1 = self.test_helpList()
        with allure.step(f"完成订单"):
            # 准备请求数据
            # json = {
            #     "id": apiKey.get_text(res1.text, 'data.list[0].id')
            # }
            json = {
                'state': '3',
                "id": apiKey.get_text(res1.text, 'data.list[0].id')
            }
            url = f"{URL}/api/help/update/state"  # 构建完整的 URL
            # url = f"{URL}/api/help/confirm"  # 构建完整的 URL
            headers = {'token': self.token}
            res2 = apiKey.post(url=url, headers=headers, json=json)
        with allure.step(f"接口返回信息校验接打印"):
            logging.info(f'完成订单接口请求响应信息:{res2.text}')
            logging.info(f'响应状态码:{res2.status_code}')
            logging.info(f'响应头:{res2.headers}')
            result = res2.json()  # 获取响应结果（只调用一次 json()）
            msg = result.get('msg', '未找到msg字段')  # 获取响应消息
            logging.info(f"响应消息：{msg}")
            # 断言响应消息
            # assert result.get('msg') == '修改成功了1条数据', (
            #     f"响应消息与预期不符\n"
            #     f"预期消息：{'修改成功了1条数据'}\n"
            #     f"实际消息：{result.get('msg')}"
            # )
            assert result.get('code') == 1, '响应状态码与预期不符'  # 断言响应状态码
            db = apiKey.db_mysql_select2()
            assert db.execute(
                f"select * from helplist where id={apiKey.get_text(res1.text, 'data.list[0].id')} and state = '3' ") != '', '完成失败'
            logging.info('完成订单业务测试通过')
        return res2

